﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using ARR.UI.Commands;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.ComponentModel;
using System.Windows.Data;
using ARR.UI.Models;
using ARR.Shared;
using ARR.UI.Views;
using System.IO;
using ARR.UI.SpacesService;

namespace ARR.UI.ViewModels
{
    public class MainWindowViewModel : ViewModelBase
    {
        private ICommand articleMasterCommand;
        private ICommand storeMasterCommand;
        private ICommand importStoresCommand;
        private ICommand rangeReviewCommand;
        private ICommand articlesImporterCommand;
        private ICommand salesImporterCommand;
        private ICommand reportCategoryViewerCommand;
        private ICommand countryMasterCommand;
        private ObservableCollection<WorkspaceViewModel> workspaces;
        private ICommand attributesMasterCommand;
        private ICommand unitsOfMeasureMasterCommand;
        private ICommand unifiedImporterCommand;
        private ICommand theoreticalMarginsCommand;
        private ICommand inventoryImporterCommand;
        private ICommand categoryMatchesCommand;
        private ICommand generalCommentsCommand;
        private ICommand categoryMasterCommand;
        private ICommand salesMasterCommand;
        private ICommand loginCommand;
        private ICommand spacesImporterCommand;
        private ICommand planogramMasterCommand;
        private ICommand pIDifferencesImporterCommand;
        private ICommand reportExecutiveSummaryCommand;
        private ICommand importHistoryCommand;
        private ICommand floorplanCommand;
        private ICommand historyCommand;

        public MainWindowViewModel()
        {
            DisplayName = Labels.NombreDeAplicacion;
        }


        public ICommand HistoryCommand
        {
            get
            {
                if (historyCommand == null)
                {
                    historyCommand = new RelayCommand(param => OpenHistoryView());
                }
                return historyCommand;
            }
        }
        
        public ICommand HistoryImporterCommand
        {
            get
            {
                if (importHistoryCommand == null)
                {
                    importHistoryCommand = new RelayCommand(param => OpenHistoryImporter());
                }
                return importHistoryCommand;
            }
        }

        public ICommand ReportCategoryViewerCommand
        {
            get
            {
                if (reportCategoryViewerCommand == null)
                {
                    reportCategoryViewerCommand = new RelayCommand(param => OpenReportCategoryViewer());
                }
                return reportCategoryViewerCommand;
            }
        }

        public ICommand ReportExecutiveSummaryCommand
        {
            get
            {
                if (reportExecutiveSummaryCommand == null)
                {
                    reportExecutiveSummaryCommand = new RelayCommand(param => OpenReportViewerExecutiveSummary());
                }
                return reportExecutiveSummaryCommand;
            }
        }
                
        public ICommand ArticleMasterCommand
        {
            get
            {
                if (articleMasterCommand == null)
                {
                    articleMasterCommand = new RelayCommand(param => OpenArticleMaster());
                }
                return articleMasterCommand;
            }
        }

        public ICommand StoreMasterCommand
        {
            get
            {
                if (storeMasterCommand == null)
                {
                    storeMasterCommand = new RelayCommand(param => OpenStoreMaster());
                }
                return storeMasterCommand;
            }
        }

        public ICommand CountryMasterCommand
        {
            get
            {
                if (countryMasterCommand == null)
                {
                    countryMasterCommand = new RelayCommand(param => OpenCountryMaster());
                }
                return countryMasterCommand;
            }
        }

        public ICommand AttributesMasterCommand
        {
            get
            {
                if (attributesMasterCommand == null)
                {
                    attributesMasterCommand = new RelayCommand(param => OpenAttributesMaster());
                }
                return attributesMasterCommand;
            }
        }

        public ICommand CategoryMasterCommand
        {
            get
            {
                if (categoryMasterCommand == null)
                {
                    categoryMasterCommand = new RelayCommand(param => OpenCategoryMaster());
                }
                return categoryMasterCommand;
            }
        }
                
        public ICommand UnitsOfMeasureMasterCommand
        {
            get
            {
                if (unitsOfMeasureMasterCommand == null)
                {
                    unitsOfMeasureMasterCommand = new RelayCommand(param => OpenUomMaster());
                }
                return unitsOfMeasureMasterCommand;
            }
        }
                        
        public ICommand ImportStoresCommand
        {
            get
            {
                if (importStoresCommand == null)
                {
                    importStoresCommand = new RelayCommand(param => OpenImportStores());
                }
                return importStoresCommand;
            }
        }

        public ICommand RangeReviewCommand
        {
            get
            {
                if (rangeReviewCommand == null)
                {
                    rangeReviewCommand = new RelayCommand(param => OpenRangeReviewManager());
                }
                return rangeReviewCommand;
            }
        }

        public ICommand ArticlesImporterCommand
        {
            get
            {
                if (articlesImporterCommand == null)
                {
                    articlesImporterCommand = new RelayCommand(param => OpenArticlesImporter());
                }
                return articlesImporterCommand;
            }
        }

        public ICommand SalesImporterCommand
        {
            get
            {
                if (salesImporterCommand == null)
                {
                    salesImporterCommand = new RelayCommand(param => OpenSalesImporter());
                }
                return salesImporterCommand;
            }
        }

        public ICommand InventoryImporterCommand
        {
            get
            {
                if (inventoryImporterCommand == null)
                {
                    inventoryImporterCommand = new RelayCommand(param => OpenInventoryImporter());
                }
                return inventoryImporterCommand;
            }
        }
        
        public ICommand UnifiedImporterCommand
        {
            get
            {
                if (unifiedImporterCommand == null)
                {
                    unifiedImporterCommand = new RelayCommand(param => OpenUnifiedImporter(), x => CanExecuteUnifiedImporter());
                }
                return unifiedImporterCommand;
            }
        }

        public ICommand TheoreticalMarginsCommand
        {
            get
            {
                if (theoreticalMarginsCommand == null)
                {
                    theoreticalMarginsCommand = new RelayCommand(param => OpenTheoreticalMargins());
                }
                return theoreticalMarginsCommand;
            }
        }

        public ICommand CategoryMatchesCommand
        {
            get
            {
                if (categoryMatchesCommand == null)
                {
                    categoryMatchesCommand = new RelayCommand(param => OpenCategoryMarginsMaster());
                }
                return categoryMatchesCommand;
            }
        }

        public ICommand GeneralCommentsCommand
        {
            get
            {
                if (generalCommentsCommand == null)
                {
                    generalCommentsCommand = new RelayCommand(param => OpenGeneralComments());
                }
                return generalCommentsCommand;
            }
        }

        public ICommand SalesMasterCommand
        {
            get
            {
                if (salesMasterCommand == null)
                {
                    salesMasterCommand = new RelayCommand(param => OpenSalesMaster());
                }
                return salesMasterCommand;
            }
        }

        public ICommand LoginCommand
        {
            get
            {
                if (loginCommand == null)
                {
                    loginCommand = new RelayCommand(param => OpenLoginScreen());
                }
                return loginCommand;
            }
        }

        public ICommand SpacesImporterCommand
        {
            get
            {
                if (spacesImporterCommand == null)
                {
                    spacesImporterCommand = new RelayCommand(param => OpenSpacesImporter());
                }
                return spacesImporterCommand;
            }
        }

        public ICommand PlanogramMasterCommand
        {
            get
            {
                if (planogramMasterCommand == null)
                {
                    planogramMasterCommand = new RelayCommand(param => OpenPlanogramsMaster());
                }
                return planogramMasterCommand;
            }
        }

        public ICommand PIDifferencesImporterCommand
        {
            get
            {
                if (pIDifferencesImporterCommand == null)
                {
                    pIDifferencesImporterCommand = new RelayCommand(param => OpenPIDifferencesImporter());
                }
                return pIDifferencesImporterCommand;
            }
        }

        public ICommand FloorplanCommand
        {
            get
            {
                if (floorplanCommand == null)
                {
                    floorplanCommand = new RelayCommand(param => GenerateFloorPlanExcel());
                }
                return floorplanCommand;
            }
        }


              



        private bool CanExecuteUnifiedImporter()
        {
            return (!WorkspaceData.Instance.Country.IsArticleMasterSeparateFile || !WorkspaceData.Instance.Country.IsStoreMasterSeparateFile);

        }
        
        public ICommand TestAreaCommand
        {
            get
            {
                return new RelayCommand(param =>
                {
                    new TestAreaView().ShowDialog();
                });
                
            }
        }

        public ObservableCollection<WorkspaceViewModel> Workspaces
        {
            get
            {
                if (workspaces == null)
                {
                    workspaces = new ObservableCollection<WorkspaceViewModel>();
                    workspaces.CollectionChanged += this.OnWorkspacesChanged;
                }
                return workspaces;
            }
        }


        void OnWorkspacesChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null && e.NewItems.Count != 0)
                foreach (WorkspaceViewModel workspace in e.NewItems)
                    workspace.RequestClose += this.OnWorkspaceRequestClose;

            if (e.OldItems != null && e.OldItems.Count != 0)
                foreach (WorkspaceViewModel workspace in e.OldItems)
                    workspace.RequestClose -= this.OnWorkspaceRequestClose;
        }

        void OnWorkspaceRequestClose(object sender, EventArgs e)
        {
            WorkspaceViewModel workspace = sender as WorkspaceViewModel;            
            workspace.Dispose();
            this.Workspaces.Remove(workspace);
        }



        private void OpenHistoryView()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(HistoryGenerationViewModel));

            if (workspace == null)
            {
                workspace = new HistoryGenerationViewModel(ModelFactory.GetInstance<IHistoryGenerationModel>());
                workspaces.Add(workspace);
            }

            this.SetActiveWorkspace(workspace);
        }

        private void OpenReportViewerExecutiveSummary()
        {
            ReportsViewer viewer = new ReportsViewer(Views.ReportType.ExecutiveSummary, WorkspaceData.Instance.RangeReview.Id, null);
            viewer.Show();
        }

        private void OpenArticlesImporter()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(ArticlesImporterViewModel));

            if (workspace == null)
            {
                workspace = new ArticlesImporterViewModel(ModelFactory.GetInstance<IArticlesImporterModel>());
                workspaces.Add(workspace);
            }

            this.SetActiveWorkspace(workspace);
        }

        private void OpenHistoryImporter()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(HistoryImporterViewModel));

            if (workspace == null)
            {
                workspace = new HistoryImporterViewModel(ModelFactory.GetInstance<IHistoryImporterModel>());
                workspaces.Add(workspace);
            }

            this.SetActiveWorkspace(workspace);
        }

        private void OpenSalesImporter()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(SalesImporterViewModel));

            if (workspace == null)
            {
                workspace = new SalesImporterViewModel(ModelFactory.GetInstance<ISalesImporterModel>());
                workspaces.Add(workspace);
            }

            this.SetActiveWorkspace(workspace);
        }
        
        private void OpenInventoryImporter()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(InventoriesImporterViewModel));

            if (workspace == null)
            {
                workspace = new InventoriesImporterViewModel(ModelFactory.GetInstance<IInventoriesImporterModel>());
                workspaces.Add(workspace);
            }

            this.SetActiveWorkspace(workspace);
        }

        private void OpenUnifiedImporter()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(UnifiedImporterViewModel));

            if (workspace == null)
            {
                workspace = new UnifiedImporterViewModel(ModelFactory.GetInstance<IUnifiedImporterModel>());
                workspaces.Add(workspace);
            }


            this.SetActiveWorkspace(workspace);
        }
                        
        private void OpenRangeReviewManager()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(RangeReviewViewModel));

            if (workspace == null)
            {
                workspace = new RangeReviewViewModel(ModelFactory.GetInstance<IRangeReviewModel>());
                workspaces.Add(workspace);
            }
            

            this.SetActiveWorkspace(workspace);
        }
        
        private void OpenStoreMaster()
        {
            WorkspaceViewModel workspace;
            workspace = GetExistingWorkspace(typeof(StoreMasterViewModel));

            if (workspace == null)
            {
                workspace = new StoreMasterViewModel(ModelFactory.GetInstance<IStoreMasterModel>());
                workspaces.Add(workspace);
            }

            this.SetActiveWorkspace(workspace);
        }

        private void OpenImportStores()
        {
            WorkspaceViewModel workspace;
            workspace = GetExistingWorkspace(typeof(StoresImporterViewModel));

            if (workspace == null)
            {
                workspace = new StoresImporterViewModel(ModelFactory.GetInstance<IStoresImporterModel>());
                workspaces.Add(workspace);
            }

            this.SetActiveWorkspace(workspace);
        }

        private void OpenArticleMaster()
        {
            WorkspaceViewModel workspace;
            workspace = GetExistingWorkspace(typeof(ArticleMasterViewModel));

            if (workspace == null)
            {
                workspace = new ArticleMasterViewModel(ModelFactory.GetInstance<IArticleMasterModel>());
                workspaces.Add(workspace);
            }

            this.SetActiveWorkspace(workspace);
        }
        
        private void OpenCountryMaster()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(CountryMasterViewModel));

            if (workspace == null)
            {
                workspace = new CountryMasterViewModel(ModelFactory.GetInstance<ICountryMasterModel>());
                workspaces.Add(workspace);
            }


            this.SetActiveWorkspace(workspace);
        }
        
        private void OpenAttributesMaster()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(AttributesMasterViewModel));

            if (workspace == null)
            {
                workspace = new AttributesMasterViewModel(ModelFactory.GetInstance<IAttributesMasterModel>());
                workspaces.Add(workspace);
            }


            this.SetActiveWorkspace(workspace);
        }
        
        private void OpenUomMaster()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(UnitsOfMeasureMasterViewModel));

            if (workspace == null)
            {
                workspace = new UnitsOfMeasureMasterViewModel(ModelFactory.GetInstance<IUnitsOfMeasureMasterModel>());
                workspaces.Add(workspace);
            }


            this.SetActiveWorkspace(workspace);
        }

        private void OpenTheoreticalMargins()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(TheoreticalMarginsViewModel));

            if (workspace == null)
            {
                workspace = new TheoreticalMarginsViewModel(ModelFactory.GetInstance<ITheoreticalMarginModel>());
                workspaces.Add(workspace);
            }


            this.SetActiveWorkspace(workspace);
        }
        
        private void OpenCategoryMarginsMaster()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(CategoryMatchMasterViewModel));

            if (workspace == null)
            {
                workspace = new CategoryMatchMasterViewModel(ModelFactory.GetInstance<ICategoryMatchMasterModel>());
                workspaces.Add(workspace);
            }


            this.SetActiveWorkspace(workspace);
        }

        private void OpenReportCategoryViewer()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(ReportCategoryViewModel));

            if (workspace == null)
            {
                workspace = new ReportCategoryViewModel(ModelFactory.GetInstance<IReportCategoryModel>());
                workspaces.Add(workspace);
            }

            this.SetActiveWorkspace(workspace);
        }
        
        private void OpenGeneralComments()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(GeneralCommentsViewModel));

            if (workspace == null)
            {
                workspace = new GeneralCommentsViewModel(ModelFactory.GetInstance<IGeneralCommentsModel>());
                workspaces.Add(workspace);
            }

            this.SetActiveWorkspace(workspace);
        }
        
        private void OpenCategoryMaster()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(CategoryMasterViewModel));

            if (workspace == null)
            {
                workspace = new CategoryMasterViewModel(ModelFactory.GetInstance<ICategoryMasterModel>());
                workspaces.Add(workspace);
            }

            this.SetActiveWorkspace(workspace);
        }

        private void OpenSalesMaster()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(SalesMasterViewModel));

            if (workspace == null)
            {
                workspace = new SalesMasterViewModel(ModelFactory.GetInstance<ISalesMasterModel>());
                workspaces.Add(workspace);
            }

            this.SetActiveWorkspace(workspace);
        }

        private void OpenLoginScreen()
        {
            LoginView vw = new LoginView();
            vw.Show();

            Helpers.WindowManager.CloseView(this);
        }

        private void OpenSpacesImporter()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(SpacesImporterViewModel));

            if (workspace == null)
            {
                workspace = new SpacesImporterViewModel(ModelFactory.GetInstance<ISpacesImporterModel>());
                workspaces.Add(workspace);
            }

            this.SetActiveWorkspace(workspace);
        }

        private void OpenPlanogramsMaster()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(PlanogramsMasterViewModel));

            if (workspace == null)
            {
                workspace = new PlanogramsMasterViewModel(ModelFactory.GetInstance<IPlanogramsMasterModel>());
                workspaces.Add(workspace);
            }

            this.SetActiveWorkspace(workspace);
        }

        private void OpenPIDifferencesImporter()
        {
            WorkspaceViewModel workspace;

            workspace = GetExistingWorkspace(typeof(PIDifferencesImporterViewModel));

            if (workspace == null)
            {
                workspace = new PIDifferencesImporterViewModel(ModelFactory.GetInstance<IPIDifferencesImporterModel>());
                workspaces.Add(workspace);
            }

            this.SetActiveWorkspace(workspace);
        }

        private void GenerateFloorPlanExcel()
        {
            Microsoft.Win32.SaveFileDialog dialog = new Microsoft.Win32.SaveFileDialog();
            dialog.DefaultExt = ".xlsx";
            dialog.Filter = "Excel File (.xlsx)|*.xlsx";

            if (dialog.ShowDialog() == true)
            {
                byte[] excelBytes = null;

                SpacesServiceClient service = new SpacesServiceClient();
                try
                {
                    excelBytes = service.GenerateFloorPlan(WorkspaceData.Instance.RangeReview.Id);
                    service.Close();
                }
                catch
                {
                    service.Abort();
                    throw;
                }

                //Generate the xslx
                if (excelBytes != null)
                {
                    File.WriteAllBytes(dialog.FileName, excelBytes);
                }
            }
        }


        private void SetActiveWorkspace(WorkspaceViewModel workspace)
        {
            Debug.Assert(this.Workspaces.Contains(workspace));

            ICollectionView collectionView = CollectionViewSource.GetDefaultView(this.Workspaces);
            if (collectionView != null)
                collectionView.MoveCurrentTo(workspace);
        }

        private WorkspaceViewModel GetExistingWorkspace(Type newViewModelType)
        {
            if (workspaces.Any(ws => ws.GetType() == newViewModelType))
            {
                return workspaces.SingleOrDefault(ws => ws.GetType() == newViewModelType);
            }

            return null;
        }
    }
}
